﻿/****************************************************
** 作者： Halower (QQ:121625933)
** 创始时间：2015-02-01
** 描述：jqGrid扩展
*****************************************************/

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Halower.JqGrid.Enum;
using Halower.JqGrid.Serializer;
using System;

namespace Halower.JqGrid.Core
{
    public class GridTable<T>:IHtmlString
    {
        #region 构造函数
        public GridTable()
        {
            GridConfiguration = new GridConfiguration();
        }

        public GridTable(string gridId)
            : this()
        {
            _gridId = gridId;
        }

        public GridTable(string gridId, GridConfiguration gridConfiguration)
            : this(gridId)
        {
            GridConfiguration = gridConfiguration;
        }

        #endregion

        #region 字段
        private readonly string _gridId;
        private bool _hasPager;
        private string _pagerId;
        #endregion

        #region 属性

        private GridConfiguration GridConfiguration { get; set; }
        #endregion
 
        #region 主要方法
        /// <summary>
        /// 启用分页
        /// </summary>
        /// <param name="pagerId">分页控件Id</param>
        /// <returns></returns>
        public GridTable<T> Pager(string pagerId)
        {
            _hasPager = true;
            _pagerId = pagerId;
            GridConfiguration.PagerId = _pagerId;
            return this;
        }

        /// <summary>
        /// 获取数据的地址
        /// </summary>
        /// <param name="postUrl">获取数据的地址</param>
        /// <param name="postData">发送参数数据</param>
        /// <returns></returns>
        public GridTable<T> Url(string postUrl, Dictionary<string, string> postData)
        {
            GridConfiguration.Url = postUrl;
            if (postData == null)
            {
                postData = new Dictionary<string, string>();
            }
            postData.Add("DisplayFileds", string.Join(",", GridConfiguration.GridColumns.Select(c => c.Field).Where(f => !string.IsNullOrEmpty(f))));
            if (string.IsNullOrEmpty(this.GridConfiguration.GridKey))
                throw new Exception("请指定表格标识列");
                postData.Add("gridkey", this.GridConfiguration.GridKey);
            GridConfiguration.PostData = postData;
            return this;
        }

        /// <summary>
        /// 表格名称
        /// </summary>
        /// <param name="caption">表格名称</param>
        /// <returns></returns>
        public GridTable<T> Caption(string caption)
        {
            GridConfiguration.Caption = caption;
            return this;
        }

        /// <summary>
        /// 一个下拉选择框，用来改变显示记录数，当选择时会覆盖rowNum参数传递到后台
        /// </summary>
        /// <param name="rowslist">显示记录数</param>
        /// <returns></returns>
        public GridTable<T> RowList(params int[] rowslist)
        {
            GridConfiguration.RowList = rowslist;
            return this;
        }

        /// <summary>
        /// 默认的排序列。可以是列名称或者是一个数字，这个参数会被提交到后台
        /// </summary>
        /// <param name="sortName">排序列</param>
        /// <returns></returns>
        public GridTable<T> SortName(string sortName)
        {
            GridConfiguration.SortName = sortName;
            return this;
        }

        /// <summary>
        ///     表格中的书写方向
        /// </summary>
        /// <param name="direction">书写方向</param>
        /// <returns></returns>
        public GridTable<T> Direction(Driections direction)
        {
            GridConfiguration.Direction = direction.ToString().ToLower();
            return this;
        }

        /// <summary>
        ///     从服务器读取XML或JSON数据时初始的排序类型
        /// </summary>
        /// <param name="sortOrderType">排序类型</param>
        /// <returns></returns>
        public GridTable<T> SortOrder(SortOrders sortOrderType=SortOrders.Desc)
        {
            GridConfiguration.Sortorder = sortOrderType.ToString().ToLower();
            return this;
        }

        /// <summary>
        ///     数据请求和排序时显示的文本
        /// </summary>
        /// <param name="loadtext">显示的文本</param>
        /// <returns></returns>
        public GridTable<T> LoadText(string loadtext)
        {
            GridConfiguration.LoadText = loadtext;
            return this;
        }

        /// <summary>
        ///     定义导航栏是否有页码输入框 
        /// </summary>
        /// <param name="haspginput">是否有页码输入框</param>
        /// <returns></returns>
        public GridTable<T> PgInput(bool haspginput)
        {
            GridConfiguration.PgInput = haspginput;
            return this;
        }

        /// <summary>
        ///     当设置为true时，表格宽度将自动匹配到父元素的宽度
        /// </summary>
        /// <param name="autowidth">自动匹配</param>
        /// <returns></returns>
        public GridTable<T> AutoWidth(bool autowidth = true)
        {
            GridConfiguration.AutoWidth = autowidth;
            return this;
        }



        /// <summary>
        /// 当设置为true时，对来自服务器的数据和提交数据进行encodes编码。如<![CDATA[<将被转换为&lt;]]>
        /// </summary>
        /// <param name="autoEncode">encodes编码</param>
        /// <returns></returns>
        public GridTable<T> AutoEencode(bool autoEncode)
        {
            GridConfiguration.AutoEencode = autoEncode;
            return this;
        }

        /// <summary>
        ///     定义表格希望获得的数据的类型
        /// </summary>
        /// <param name="dataTypes">数据的类型</param>
        /// <returns></returns>
        public GridTable<T> DataType(ResponseDatas dataTypes)
        {
            GridConfiguration.DataType = dataTypes.ToString().ToLower();
            return this;
        }

        /// <summary>
        ///     当返回(或当前)数量为零时显示的信息此项只用当viewrecords 设置为true时才有效。
        /// </summary>
        /// <param name="emptyrecords">数量为零时显示的信息</param>
        /// <returns></returns>
        public GridTable<T> EmptyRecords(string emptyrecords)
        {
            GridConfiguration.EmptyRecords = emptyrecords;
            return this;
        }

        /// <summary>
        ///     表格高度。可为数值、百分比或auto
        /// </summary>
        /// <param name="height">高度</param>
        /// <returns></returns>
        public GridTable<T> Height(string height)
        {
            GridConfiguration.Height = height;
            return this;
        }

        /// <summary>
        ///     此属性设为true时启用多行选择，出现复选框
        /// </summary>
        /// <param name="multiselect">出现复选框</param>
        /// <returns></returns>
        public GridTable<T> Multiselect(bool multiselect = true)
        {
            GridConfiguration.Multiselect = multiselect;
            return this;
        }

        /// <summary>
        /// 子表数据请求Url
        /// </summary>
        /// <param name="url">数据请求Url</param>
        /// <returns></returns>
        public GridTable<T> SubGridUrl(string url)
        {
            GridConfiguration.SubGrid = true;
            if(!url.Contains("?")&&!url.EndsWith("\\"))
                GridConfiguration.SubGridUrl = url + "?displayfileds=" + string.Join(",", GridConfiguration.SubGridModel[0].GridColumns.Select(c => c.Field).Where(f => !string.IsNullOrEmpty(f)));
            return this;
        }

        /// <summary>
        /// 设置子表获取数据时所依赖父表字段
        /// </summary>
        /// <param name="paramsters">获取数据时所依赖父表字段</param>
        /// <returns></returns>
        public GridTable<T> SubGridPostParams(params string[] paramsters)
        {
            GridConfiguration.SubGridModel[0].Params = paramsters;
            return this;
        }

        /// <summary>
        /// 子表格列配置
        /// </summary>
        /// <param name="gridColumns">有效列</param>
        /// <returns></returns>
        public GridTable<T> MainGrid(params GridColumn[] gridColumns)
        {
            GridConfiguration.GridColumns = gridColumns.ToList();
            return this;
        }
         /// <summary>
        /// 子表格列配置
        /// </summary>
        /// <param name="multisearh">开启高级查询</param>
        /// <returns></returns>
        public GridTable<T> MultiSearch(bool multisearh=true)
        {
            GridConfiguration.MultiSearch = multisearh;
            return this;
        }


        /// <summary>
        /// 子表格列配置
        /// </summary>
        /// <param name="gridColumns">有效列</param>
        /// <returns></returns>
        public GridTable<T> SubGrid(params  GridColumn[] gridColumns)
        {
            GridConfiguration.SubGridModel =new[]{new SubGridTable(gridColumns)};
            return this;
        }
        public GridTable<T> GridKey(string gridKey)
        {
            GridConfiguration.GridKey = gridKey ;
            return this;
        }
        /// <summary>
        /// 启用内置操作类型
        /// </summary>
        /// <param name="gridOperatorTypes">内置操作类型</param>
        /// <returns></returns>
        public GridTable<T> BuiltInOperation(GridOperators gridOperatorTypes)
        {
            if (gridOperatorTypes.HasFlag(GridOperators.Add))
                GridConfiguration.GridOperation.Add = true;
            if (gridOperatorTypes.HasFlag(GridOperators.Edit))
                GridConfiguration.GridOperation.Edit = true;
            if (gridOperatorTypes.HasFlag(GridOperators.Delete))
                GridConfiguration.GridOperation.Delete = true;
            if (gridOperatorTypes.HasFlag(GridOperators.Search))
                GridConfiguration.GridOperation.Search = true;
            return this;
        }

        public GridTable<T> GroupHeaders(params GroupHeader[] groupHeaders)
        {
            GridConfiguration.GroupHeaders = true;
            GridConfiguration.ColSPanConfiguation.GroupHeaders = groupHeaders;
            return this;
        }
        /// <summary>
        /// 表格生成器
        /// </summary>
        /// <returns></returns>
        public string ToHtmlString()
        {
            var tableContainer = TableBuilder();
            //===============JS代码==================//
            var gridHtml = string.Format("jQuery(\"#{0}\").jqGrid(", _gridId);
            var jsContainer = new TagBuilder("script");
            var jsBulider = new StringBuilder("$(function(){");
            //表格初始化
            jsBulider.AppendFormat(gridHtml+"{0});", GridConfiguration.ToSerializerIgnoreNullValue());
            //操作按钮控制
            jsBulider.AppendFormat(gridHtml + "'navGrid', '{0}',{1},{{}},{{}},{{}}{2});",
                GridConfiguration.PagerId, GridConfiguration.GridOperation.ToSerializerIgnoreNullValue(), GridConfiguration.MultiSearch?",{multipleSearch:true}":"");
            //行合并控制
            if (GridConfiguration.GroupHeaders)
            {
                jsBulider.AppendFormat(gridHtml + "'setGroupHeaders',{0});", GridConfiguration.ColSPanConfiguation.ToSerializerIgnoreNullValue());
            }
            jsBulider.Append("})");
            //===============JS代码==================//
            jsContainer.InnerHtml =jsBulider.ToString().Replace("\"&", "").Replace("&\"", "");
            return tableContainer + jsContainer.ToString();
        }

        private StringBuilder TableBuilder()
        {
            var tabBuider = new TagBuilder("table");
            tabBuider.GenerateId(_gridId);
            var builder = new StringBuilder(tabBuider.ToString());
            if (!_hasPager) return builder;
            var pagerBuilder = new TagBuilder("div");
            pagerBuilder.GenerateId(_pagerId);
            builder.Append(pagerBuilder);
            return builder;
        }

        public override string ToString()
        {
            var result=ToHtmlString();
            return result;
        }
        #endregion

      
    } 
}

